package com.jfs.zlk.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.jfs.cmd.SIPCommander;
import com.jfs.session.VideoStreamSessionManager;
import com.jfs.zlk.controller.entity.*;
import com.jfs.zlk.entity.ZlkResult;
import com.jfs.zlk.provider.ZlkMediaServerAbilityProvider;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

/**
 * @Description zlk流媒体服务器web事件钩子
 * @E-mail cwm3412638@163.com
 * @Author cwm
 * @Date 2022/7/28
 */
@RestController
@Slf4j
@RequestMapping("/index/hook")
@AllArgsConstructor
public class ZlkMediaServerWebHook {
    private final SIPCommander sipCommander;
    private final ZlkMediaServerAbilityProvider zlkMediaServerAbilityProvider;

    /**
     * 流量统计事件，播放器或推流器断开时并且耗用流量超过特定阈值时会触发此事件
     *
     * @param onFlowReport
     * @return
     */
    @PostMapping("/on_flow_report")
    public ResponseEntity<String> onFlowReport(@RequestBody OnFlowReport onFlowReport) {
        if (log.isDebugEnabled()) {
            log.debug("发生流量统计事件：{}", JSONUtil.toJsonStr(onFlowReport));
        }
        return new ResponseEntity<String>(JSONUtil.toJsonStr(ZlkResult.Ok()), HttpStatus.OK);
    }

    /**
     * 服务器定时上报时间，上报间隔可配置，默认10s上报一次
     *
     * @param json
     */
    @PostMapping("/on_server_keepalive")
    public void onServerKeepalive(@RequestBody JSONObject json) {
        if (log.isDebugEnabled()) {
            log.debug("zlk流媒体服务器心跳事件：{}", JSONUtil.toJsonStr(json));
        }
    }

    /**
     * rtsp/rtmp流注册或注销时触发此事件；此事件对回复不敏感。
     *
     * @param onStreamChanged
     * @return
     */
    @PostMapping("/on_stream_changed")
    public ResponseEntity<String> onStreamChanged(@RequestBody OnStreamChanged onStreamChanged) {
        if (log.isDebugEnabled()) {
            if (Objects.nonNull(onStreamChanged)) {
                if (onStreamChanged.getRegist()) {
                    log.debug("注册流成功,流应用名:{},流ID:{},方式为:{}", onStreamChanged.getApp(), onStreamChanged.getStream(), onStreamChanged.getSchema());
                } else {
                    log.debug("注销流成功,流应用名:{},流ID:{},方式为:{}", onStreamChanged.getApp(), onStreamChanged.getStream(), onStreamChanged.getSchema());
                }

            }
        }
        return new ResponseEntity<String>(JSONUtil.toJsonStr(ZlkResult.Ok()), HttpStatus.OK);
    }

    /**
     * 流无人观看时事件，用户可以通过此事件选择是否关闭无人看的流
     */
    @PostMapping("/on_stream_none_reader")
    public ResponseEntity<String> onStreamNoneReader(@RequestBody OnStreamNoneReader onStreamNoneReader) {
        if (log.isDebugEnabled()) {
            if (Objects.nonNull(onStreamNoneReader)) {
                log.debug("无人观看直播流触发事件,流应用名:{},流ID:{},方式为:{}", onStreamNoneReader.getApp(), onStreamNoneReader.getStream(), onStreamNoneReader.getSchema());
            }
        }
        if (StrUtil.isNotEmpty(onStreamNoneReader.getStream())) {
            String channelId = VideoStreamSessionManager.getChannelId(onStreamNoneReader.getStream());
            if (StrUtil.isNotEmpty(channelId)) {
                boolean b = sipCommander.streamByeCmd(onStreamNoneReader.getStream(), channelId);
                if (b) {
                    //恢复推流端口
                    Integer portByChannel = VideoStreamSessionManager.getPortByChannel(onStreamNoneReader.getStream());
                    if (Objects.nonNull(portByChannel)) {
                        zlkMediaServerAbilityProvider.addProtRange(portByChannel);
                    }
                }
                if (log.isDebugEnabled()) {
                    log.debug("关闭流：{}", b ? "成功" : "失败");
                }
            }
        }
        ResponseOnStreamNoneReader responseOnStreamNoneReader = new ResponseOnStreamNoneReader(0, true);
        return new ResponseEntity<String>(JSONUtil.toJsonStr(responseOnStreamNoneReader), HttpStatus.OK);
    }

    /**
     * 播放器鉴权事件，rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。
     */
    @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8")
    public ResponseEntity<String> onPlay(@RequestBody OnPlay onPlay) {

        if (log.isDebugEnabled()) {
            log.debug("播放器鉴权事件,流应用名:{},流ID:{},方式为:{}", onPlay.getApp(), onPlay.getStream(), onPlay.getSchema());
        }
        ResponseOnPlay success = new ResponseOnPlay(0, "success");
        return new ResponseEntity<String>(JSONUtil.toJsonStr(success), HttpStatus.OK);
    }


    /**
     * rtsp/rtmp/rtp推流鉴权事件。
     */
    @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8")
    public ResponseEntity<String> onPublish(@RequestBody OnPublish onPublish) {
        if (log.isDebugEnabled()) {
            log.debug("rtsp/rtmp/rtp推流鉴权事件,流应用名:{},流ID:{},方式为:{}", onPublish.getApp(), onPublish.getStream(), onPublish.getSchema());
        }
        ResponseOnPublish success = new ResponseOnPublish(0, true, false, "success");
        return new ResponseEntity<String>(JSONUtil.toJsonStr(success), HttpStatus.OK);
    }
}
